---
title: 导入
description: 学习如何在 Astro 中导入不同类型的内容。
i18nReady: true
---
import RecipeLinks from "~/components/RecipeLinks.astro";
import ReadMore from '~/components/ReadMore.astro'

Astro 无需配置即支持大多数静态资源。你可以在项目的任何地方使用 `import` 语句（包括 Astro frontmatter 脚本），Astro 将在最终构建中内置优化后的静态资源副本。在 CSS 和 `<style>` 标签中也可以使用 `@import`。

## 受支持的文件类型

下面的文件类型 Astro 开箱即用：

- Astro 组件 (`.astro`)
- Markdown (`.md`，`.markdown`，等等)
- JavaScript (`.js`，`.mjs`)
- TypeScript (`.ts`，`.tsx`)
- NPM 包
- JSON (`.json`)
- JSX (`.jsx`，`.tsx`)
- CSS (`.css`)
- CSS 模块 (`.module.css`)
- 图片和资源 (`.svg`，`.jpg`，`.png`，等等。)

此外，你可以扩展 Astro 以添加对不同 [UI 框架](/zh-cn/guides/framework-components/)的支持，如 React、Svelte 和 Vue 组件。你还可以安装 [Astro MDX 集成](/zh-cn/guides/integrations-guide/mdx/)并在项目中使用 `.mdx` 文件。

### `public/` 中的文件

你可以将任何静态资源放在项目的 [`public/` 目录](/zh-cn/basics/project-structure/#public)中，Astro 将直接将其复制到最终构建中，而不会对其进行任何处理。`public/` 文件不会被 Astro 构建或打包，这意味着支持任何类型的文件。你可以在 HTML 模板中直接通过 URL 路径引用 `public/` 文件。

## Import 语句

Astro 使用 ESM，它是浏览器中支持的相同 [`import`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import#syntax) 和 [`export`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/export) 语法。

### JavaScript

```js
import { getUser } from './user.js';
```

可以使用普通的 ESM `import` 和 `export` 语法来导入 JavaScript。它在 Node.js 和浏览器中和预期保持一致。

### TypeScript

```js
import { getUser } from './user';
import type { UserType } from './user';
```

Astro 内置对 [TypeScript](https://www.typescriptlang.org/) 的支持。你可以在 Astro 项目中直接导入 `.ts` 和 `.tsx` 文件，甚至可以直接在 [Astro 组件脚本](/zh-cn/basics/astro-components/#组件脚本)和任意 [hoisted script 标签](/zh-cn/guides/client-side-scripts/) 中编写 TypeScript 代码。

**Astro 本身不进行任何类型检查**。类型检查应该在 Astro 之外进行或由 IDE 或通过一个单独的脚本来处理。[Astro VSCode 扩展](/zh-cn/editor-setup/) 会自动为打开的文件中提供 TypeScript 提示和错误警告。或使用 [`astro check` 命令](/zh-cn/reference/cli-reference/#astro-check) 检查 Astro 文件的类型。

:::note[TypeScript 和文件扩展名]
根据 [TypeScript 模块解决方案规则](https://www.typescriptlang.org/docs/handbook/module-resolution.html)，`.ts` 和 `.tsx` 文件扩展名不应该在导入 TypeScript 文件时使用。相反，要么使用`.js`/`.jsx`文件扩展名，要么完全省略文件扩展名。

```ts
import { getUser } from './user.js'; // user.ts
import MyComponent from "./MyComponent"; // MyComponent.tsx
```

:::

<ReadMore>了解更多关于 [Astro 中的 TypeScript 支持](/zh-cn/guides/typescript/) 的内容。</ReadMore>

### JSX / TSX

```js
import { MyComponent } from './MyComponent.jsx';
```

Astro 内置对 JSX（`*.jsx`和`*.tsx`）文件的支持。JSX 语法会自动转译为 JavaScript。

虽然 Astro 能理解 JSX 语法，但你需要使用框架集成来正确渲染 React、Preact 和 Solid 等框架。请查看我们的[使用集成](/zh-cn/guides/integrations-guide/)指南以了解更多。

:::note
**Astro 不支持 `.js`/`.ts` 文件中的 JSX 语法。**只有以`.jsx` 和 `.tsx` 文件扩展名结尾的文件中的 JSX 才会被处理。
:::

### NPM 包

如果你安装了一个 NPM 包，你可以在 Astro 中导入它。

```astro
---
import { Icon } from 'astro-icon';
---
```
如果一个包使用了旧的格式发布，Astro 将尝试将包转换为 ESM，以便 `import` 语句可以正常工作。在某些情况下，你可能需要调整你的 [`vite` 配置](/zh-cn/reference/configuration-reference/#vite) 以使其正常工作。

:::caution
一些包依赖于浏览器环境。Astro 组件在服务器上运行，因此在 frontmatter 导入这些包可能会[导致错误](/zh-cn/guides/troubleshooting/#document-or-window-is-not-defineddocument-或-window-对象未定义)。
:::

### JSON

```js
// 使用默认导入加载 JSON 对象
import json from './data.json';
```

Astro 支持直接在应用程序中导入 JSON 文件。导入文件会通过默认导入返回完整的 JSON 对象。

### CSS

```js
// 加载并将 'style.css' 注入到页面上。
import './style.css';
```

Astro 支持直接在应用程序中导入 CSS 文件。导入的样式没有暴露出口，但导入样式会自动将这些样式添加到页面中。它默认支持所有 CSS 文件，并且可以通过插件支持 CSS 编译语言，如 Sass & Less。

### CSS 模块

```jsx
// 1. 将 './style.module.css' 转换为类名唯一、有范围的值。
// 2. 返回对象，并将原始类名映射到其最终范围值的。
import styles from './style.module.css';

// This example uses JSX, but you can use CSS Modules with any framework.
return <div className={styles.error}>Your Error Message</div>;
```

Astro 支持使用 `[name].module.css` 命名约定的 CSS 模块。像导入任何 CSS 文件一样，导入 CSS 会应用到页面。然而，CSS 模块默认导出特殊的 `styles` 对象，并将你的原始类名映射到唯一的标识符。

CSS 模块帮助你在前端强制执行组件样式隔离，并生成唯一的样式表类名。

### 其他资源

```jsx
import imgReference from './image.png'; // img === '/src/image.png'
import svgReference from './image.svg'; // svg === '/src/image.svg'
import txtReference from './words.txt'; // txt === '/src/words.txt'

// 这个例子使用 JSX，但你可以在任何框架下使用导入引用。
<img src={imgReference.src} alt="image description" />;
```

所有其他没有明确提到的资源可以通过 ESM 的 `import` 语句导入，并将返回最终构建中的资源引用连接。这对使用链接引用非 JS 资源很有用，比如创建一个带有 `src` 属性的图片元素指向该图片。

将图片放在 `public/` 文件夹中也很有用，这在[项目结构页面](/zh-cn/basics/project-structure/#public)中有所解释。

:::note
鼓励将**替代文本**添加到 `<img>` 标记以提高可访问性！不要忘记向图像元素添加 `alt="一段有用的描述"` 属性。如果图像纯粹是装饰性的，则可以将该属性留空。
:::

## `Astro.glob()`

[`Astro.glob()`](/zh-cn/reference/api-reference/#astroglob) 是一种一次性导入多个文件的方法。

`Astro.glob()` 只接受一个参数：一个相对的 [glob 模式](/zh-cn/guides/imports/#glob-模式) 匹配你想要导入的本地文件。它是异步的，并返回每个匹配文件的导出数组。

```astro title="src/components/my-component.astro"
---
// 导入`./src/pages/post/` 中所有以 `.md` 结尾的文件
const posts = await Astro.glob('../pages/post/*.md');
---
<!-- 把前 5 篇博客文章渲染成 <article> -->
<div>
{posts.slice(0, 4).map((post) => (
  <article>
    <h2>{post.frontmatter.title}</h2>
    <p>{post.frontmatter.description}</p>
    <a href={post.url}>Read more</a>
  </article>
))}
</div>
```

使用 `Astro.glob` 导入的 Astro 组件的类型为 [`AstroInstance`](/zh-cn/reference/api-reference/#astro-文件)。你可以使用其 `default` 属性渲染每个组件实例：

```astro title="src/pages/component-library.astro" {8}
---
// 导入`./src/components/` 中所有以 `.astro` 结尾的文件
const components = await Astro.glob('../components/*.astro');
---
<!-- 展示所有组件-->
{components.map((component) => (
  <div>
    <component.default size={24} />
  </div>
))}
```


### Glob 模式

glob 模式是一个支持特殊通配符的文件路径。用于一次引用项目中的多个文件。

例如，glob 模式 `./pages/**/*.{md,mdx}` 从 pages 子目录开始，查找其所有子目录（`/**`），并匹配以 `.md` 或 `.mdx` 结尾的任何文件名（`.{md,mdx}`）。

#### Astro 中的 Glob 模式

要与 `Astro.glob()` 一起使用，glob 模式必须是字符串字面量，并且不能包含任何变量。有关解决方法，请参阅[故障排除指南](/zh-cn/guides/troubleshooting/#astroglob---没有找到匹配项)。

此外，glob 模式必须以以下之一开头：
- `./`（从当前目录开始）
- `../`（从父目录开始）
- `/`（从项目根目录开始）

[阅读更多关于 glob 模式语法](https://github.com/mrmlnc/fast-glob#pattern-syntax)


#### `Astro.glob()` vs `getCollection()`

[内容集合](/zh-cn/guides/content-collections/) 提供用于加载多个文件的 [`getCollection()` API](/zh-cn/reference/api-reference/#getcollection) 代替 `Astro.glob()`。如果你的内容文件 (例如 Markdown, MDX, Markdoc) 位于`src/content/` 目录内的集合中，使用 `getCollection()` [查询集合](/zh-cn/guides/content-collections/#查询集合)并返回内容条目。



## WASM

```js
// 加载并初始化所请求的 WASM 文件
const wasm = await WebAssembly.instantiateStreaming(fetch('/example.wasm'));
```

Astro 支持使用浏览器的 [`WebAssembly`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly) API 直接在应用程序中 WASM 文件。

## Node 内置模块

我们鼓励 Astro 用户尽可能避免使用 Node.js 内置模块（`fs`、`path` 等）。Astro 兼容多个运行时使用 [适配器](/zh-cn/guides/server-side-rendering/)。这包括 [Deno](https://github.com/denoland/deno-astro-adapter) 和 [Cloudflare Workers](/zh-cn/guides/integrations-guide/cloudflare/)，它们不支持 Node 内置模块，例如 `fs`。

我们致力于为常用的 Node.js 内置模块提供 Astro 化的替代品，不过现在还没有实现。因此，如果你**真的**需要，我们不会阻止你使用这些内置模块。Astro 支持使用较新 `node:` 前缀来支持 Node.js 内置模块。例如，如果你想读取一个文件，你可以这样做：

```astro title="src/components/MyComponent.astro"
---
// 示例：从 Node.js 中导入内置模块 "fs/promises"
import fs from 'node:fs/promises';

const url = new URL('../../package.json', import.meta.url);
const json = await fs.readFile(url, 'utf-8');
const data = JSON.parse(json);
---

<span>Version: {data.version}</span>
```

## 扩展文件类型支持

使用 **Vite** 和兼容的 **Rollup** 插件，你可以导入 Astro 原生不支持的文件类型。在 Vite 文档的[查找插件](https://cn.vitejs.dev/guide/using-plugins.html#finding-plugins) 部分了解你需要的插件。

:::note[插件配置]
请参阅插件的文档以了解配置选项以及如何正确安装它。
:::

<RecipeLinks slugs={["zh-cn/recipes/add-yaml-support"]} />
